const config = require('../configs');
const ChainsqlAPI = require('chainsql');
const sAllAccount_Grant = 'zzzzzzzzzzzzzzzzzzzzBZbvji';

class Chainsql {
  static con;
  //初始化
  async init() {
    if (!Chainsql.con || !Chainsql.con.api.isConnected()) {
      Chainsql.con = new ChainsqlAPI();
      console.log(config.chainsql.ws);
      await Chainsql.con.connect(config.chainsql.ws);
      console.log('connect success');
    }
    this.c = Chainsql.con;
  }

  //初始化activate account
  async initActivate() {
    this.c.as(config.chainsql.root);
    await this.pay(config.chainsql.activate.address, 100000);
    console.log('initActivate success');
  }

  //激活tableOwner账户
  async initTableOwner() {
    this.c.as(config.chainsql.root);
    await this.pay(config.chainsql.tableOwner.address, 100000);
    console.log('initIssuer success');
  }

  //激活账户
  async activate(address) {
    this.c.as(config.chainsql.activate);
    return await this.pay(address, config.chainsql.activateAmount);
  }

  generateAddress() {
    return this.c.generateAddress({ algorithm: 'softGMAlg' });
  }

  //转账
  async pay(address, amount) {
    return await this.c.pay(address, { value: amount }).submit({
      expect: 'validate_success'
    });
  }

  //支付积分币
  async payJFB(address, amount) {
    this.c.as(config.chainsql.activate);
    var options = {
      value: amount,
      currency: config.chainsql.pointCoin,
      issuer: config.chainsql.chainAdmin
    };
    return await this.c.pay(address, options).submit({
      expect: 'validate_success'
    });
  }
  //设置代币网关
  async accountSet() {
    // this.c.as(config.chainsql.activate);
    var options = {
      enableRippling: true,
      rate: 1.0,
      min: 0
    };
    await this.c.accountSet(options).submit({ expect: 'validate_success' });

    console.log('accountSet success');
  }

  //信任网关
  async trustSet(account) {
    this.c.as(account);

    var options = {
      value: '99999999900',
      currency: config.chainsql.pointCoin,
      issuer: config.chainsql.chainAdmin
    };
    return await this.c
      .trustSet(options)
      .submit({ expect: 'validate_success' });
  }

  //创建表
  async createTable(tableName, fields) {
    console.log(`-----------create ${tableName} <<<<<<<<<<<<<`);
    this.c.as(config.chainsql.tableOwner);
    await this.c
      .createTable(tableName, fields)
      .submit({
        expect: 'db_success'
      })
      .catch(function (err) {
        console.log(`create ${tableName} err:`, err);
      });
  }

  //创建表
  async dropTable(tableName, fields) {
    console.log(`-----------drop ${tableName} <<<<<<<<<<<<<`);
    this.c.as(config.chainsql.tableOwner);
    await this.c
      .dropTable(tableName)
      .submit({
        expect: 'db_success'
      })
      .catch(function (err) {
        console.log(`drop ${tableName} err:`, err);
      });
  }

  //授权表
  async grant(tableName, address) {
    if (!address) {
      address = sAllAccount_Grant;
    }
    this.c.as(config.chainsql.tableOwner);
    var raw = {
      select: true,
      insert: true,
      update: true
    };
    var res = await this.c
      .grant(tableName, address, raw)
      .submit({
        expect: 'validate_success'
      })
      .catch(function (err) {
        console.log(`grant ${tableName} err:`, err);
      });
    console.log(res);
  }

  //插入表
  async insertTable(tableName, raw) {
    this.c.as(config.chainsql.tableOwner);
    return await this.c
      .table(tableName)
      .insert(raw, 'id')
      .submit({ expect: 'db_success' });
  }

  //获取区块信息
  async getLedgerInfo(index) {
    const opts = {
      ledgerVersion: index,
      includeAllData: false,
      includeTransactions: true,
      includeState: false
    };
    return await this.c.getLedger(opts);
  }

  //查询余额
  async getBalances(address, currency) {
    var options = {
      currency: currency || 'ZXC'
    };
    try {
      let res = await this.c.api.getBalances(address, options);
      if (res.length == 0) {
        return 0;
      } else {
        if (options.currency != 'ZXC') {
          for (let i = 0; i < res.length; i++) {
            if (res[i].counterparty == config.chainsql.chainAdmin) {
              return res[i].value;
            }
          }
          return 0;
        } else {
          return res[0].value;
        }
      }
    } catch (error) {
      return 0;
    }
  }

  //查询交易区块高度
  async getLedger(tx) {
    let res = await this.c.getTransaction(tx);
    return res.outcome.ledgerVersion;
  }

  async submit(signedTx) {
    var res = await this.c.api.submit(signedTx);
    if (res.resultCode != 'tesSUCCESS') {
      throw new Error(res.resultCode);
    }
  }
}

exports = module.exports = new Chainsql();
